package com.yunkeji.config.print;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Set;

/**
 * @Description 打印请求信息
 *
 * @author 老张
 * @category
 * @date 2019年12月12日 下午5:50:26
 * @version V0.1
 */
@Aspect
@Component
@Slf4j
@Profile({"prod", "test"})
public class InfoPrintProd {

    @Autowired private ObjectMapper objectMapper;

    // 使用此注解才可以进入打印
    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void webLog() {}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                        .getRequest();
        if (request.getRequestURI().contains("/v3/api-docs")) {
            return;
        }

        log.info("------------Action Info Start------------");
        byte[] bodyBytes = ServletUtil.getBodyBytes(request);
        String str = StrUtil.str(bodyBytes, "UTF-8");
        log.info("请求参数:  ->\t ");
        if (StrUtil.isNotEmpty(str)) {
            request.setAttribute("originBody", JSONUtil.parseObj(str));
            log.info(JSONUtil.toJsonPrettyStr(str));
        }
        log.info("请求路径:->\t " + request.getRequestURI());
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<Map.Entry<String, String[]>> entrySet = parameterMap.entrySet();
        for (Map.Entry<String, String[]> entry : entrySet) {
            try {
                log.info("请求参数:  ->\t " + entry.getKey() + " = " + entry.getValue()[0]);
            } catch (ArrayIndexOutOfBoundsException e) {
            }
        }
    }

    @AfterReturning(returning = "response", pointcut = "webLog()")
    public void doAfterReturning(Object response) throws Throwable {
        if (response != null && SpringUtil.getActiveProfile().equals("test")) {
            try {
                log.info("响应数据:  ->\t ");
                log.info(JSONUtil.toJsonPrettyStr(objectMapper.writeValueAsString(response)));
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        log.info("------------Action Info End------------");
    }
}
